import { config, UserBaseConfig } from './config';
import type { Configtype, SelectableConfig, BaseConfig} from './type';
import { createExtendedFunction } from './type';
import {
	margeconfig,
	getLighterColor,
	compareObject,
	drawCross,
	formatData
} from './util/index';
import { ColorError } from './util/error';
let prettyLogconfig: Configtype = config;
let Log:any
let returnLog:any
class LogQueue{
	queue: Promise<void>;
	constructor (){
	    this.queue = Promise.resolve();
	}
	add (fn: () => void) {
	    this.queue = this.queue.then(()=>fn());
	}
}
let queue = new LogQueue();

function setconfig(newConfig: SelectableConfig<Configtype>) {
	if (Object.keys(newConfig).length === 0) {
		return;
	}
	prettyLogconfig = margeconfig(prettyLogconfig, newConfig);
}
function prettyLog(newconfig: Configtype, userkey?:string) {
	function base(content: any, title?: string | number) {
		const {infotitle, infoconfig} = getinfo('base', newconfig ,title);
		setProductionLog(content, infoconfig, infotitle);
	}
	function info(content: any, title?: string | number) {
		const {infotitle, infoconfig} = getinfo('info',newconfig, title);
		setProductionLog(content, infoconfig, infotitle);
	}
	function success(content: any, title?: string | number) {
		const {infotitle, infoconfig} = getinfo('success',newconfig , title);
		setProductionLog(content, infoconfig, infotitle);
	}
	function error(content: any, title?: string | number) {
		const {infotitle, infoconfig} = getinfo('error',newconfig, title);
		setProductionLog(content, infoconfig, infotitle);
		
	}
	function warning(content: any, title?: string | number) {
		const {infotitle, infoconfig} = getinfo('error',newconfig, title);
		setProductionLog(content, infoconfig, infotitle);
	}
	function setProductionLog(content:any,infoconfig:any,infotitle:any){
		// @ts-ignore
		if(import.meta.env.MODE === 'production'){
			if (prettyLogconfig.production){
				baseLog(content, infoconfig, infotitle);
			} else {
				return;
			}
		} else {
			baseLog(content, infoconfig, infotitle);
		}
	}
	function baseLog(
		content: any,
		baseConfig: BaseConfig,
		title: string | number,
	) {
		queue.add(() => {
		    return new Promise((resolve: (value: void) => void) => {
				let hasborder = newconfig.hasborder;
				if(typeof content === 'object' && content !== null) {
					content = formatData(content, newconfig.maxDepth);
					hasborder = false; // 如果内容是对象，则不显示边框
				}
		
				let dataURL;
				let canvas = document.createElement('canvas');
				// 提高 canvas 的渲染分辨率，比如 64x64
				const scaleFactor = 8; // 放大倍数
				canvas.height = 8 * scaleFactor;
				canvas.width = 8 * scaleFactor;
				if (userkey) {
					let useravatar = prettyLogconfig.use.userList.find((item) => item.name === userkey)?.avatar;
					if (useravatar) {
						try {
							new URL(useravatar); // 验证头像是否为有效的URL
						} catch (error) {
							throw new ColorError('用户配置的头像必须是有效的URL');
						}
						
						const img = new Image();
						img.src = useravatar;
						img.crossOrigin = 'anonymous'; // 设置跨域属性
						img.onload = () => {
							const ctx = canvas.getContext('2d');
							if (ctx) {
								// 绘制圆形裁剪区域
								ctx.beginPath();
								ctx.arc(canvas.width / 2, canvas.height / 2, canvas.width / 2, 0, Math.PI * 2);
								ctx.closePath();
								ctx.clip();
								ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
								dataURL = canvas.toDataURL('image/png');
								
								// 确保在头像加载完成后打印，使用 scaleFactor 缩小显示尺寸
								console.log(`%c x %c ${title} %c ${content} %c`, 
									`background-image: url(${dataURL});
									background-repeat: no-repeat;
									background-size: cover;
									width: 8px;
									height: 8px;
									padding: ${canvas.height / scaleFactor + 2}px ${canvas.width / scaleFactor}px;
									border-radius: 50%;
									color: transparent;
									margin: 3px;`,
									`background:${baseConfig.backgroundColor}; border:1px solid ${baseConfig.borderColor}; border-radius: 2px 0 0 2px; color:${baseConfig.titleColor}`,
									` ${hasborder ? `border: 1px dashed ${baseConfig.borderColor};` : ''};,
									padding: 1px;
									border-radius:0 2px 2px 0;
									color:${baseConfig.contentColor};
									`,
									`background: transparent`
								);
								resolve()
							}
						};
					}else {
						console.log(`%c ${title} %c ${content} %c`,
							`background:${baseConfig.backgroundColor}; border:1px solid ${baseConfig.borderColor}; border-radius: 2px 0 0 2px; color:${baseConfig.titleColor}`, ` ${hasborder ? `border: 1px dashed ${baseConfig.borderColor};` : ''};,
							padding: 1px;
							border-radius:0 2px 2px 0;
							color:${baseConfig.contentColor};
							`, `background: transparent`);
							resolve()
					}
				} else {
					console.log(`%c ${title} %c ${content} %c`,
						`background:${baseConfig.backgroundColor}; border:1px solid ${baseConfig.borderColor}; border-radius: 2px 0 0 2px; color:${baseConfig.titleColor}`, ` ${hasborder ? `border: 1px dashed ${baseConfig.borderColor};` : ''};,
						padding: 1px;
						border-radius:0 2px 2px 0;
						color:${baseConfig.contentColor};
						`, `background: transparent`);
						resolve()
				}
			})
		})	
	}
	function picture(imgurl: string) {
		// @ts-ignore
		if(import.meta.env.MODE === 'production' && !newconfig.production){
			return;
		}
		return new Promise((resolve: any) => {
		    const img = new Image();
			img.src = imgurl;
			img.crossOrigin = 'anonymous'; // 设置跨域属性
			img.onload = () => {
				const canvas = document.createElement('canvas');
				const ctx = canvas.getContext('2d');
				if (ctx) {
					const imgheigth = img.height;
					const imgwidth = img.width;
					if (
						imgheigth < newconfig.img.maxHeight &&
						imgwidth < newconfig.img.maxWidth
					) {
						canvas.width = imgwidth;
						canvas.height = imgheigth;
					} else if (
						imgheigth > newconfig.img.maxHeight &&
						imgwidth < newconfig.img.maxWidth
					) {
						const heightRatio =
						newconfig.img.maxHeight / imgheigth;
						canvas.width = imgwidth * heightRatio;
						canvas.height = newconfig.img.maxHeight;
					} else if (
						imgheigth < newconfig.img.maxHeight &&
						imgwidth > newconfig.img.maxWidth
					) {
						const widthRatio = newconfig.img.maxWidth / imgwidth;
						canvas.width = newconfig.img.maxWidth;
						canvas.height = imgheigth * widthRatio;
					} else {
						const heightRatio =
						newconfig.img.maxHeight / imgheigth;
						const widthRatio = newconfig.img.maxWidth / imgwidth;
						const ratio = Math.min(heightRatio, widthRatio);
						canvas.width = imgwidth * ratio;
						canvas.height = imgheigth * ratio;
					}
					ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
					let dataURL = canvas.toDataURL('image/png');
					console.log(
						'%c sup?',
						`background-image: url(${dataURL});
							background-repeat: no-repeat;
							background-size: ${canvas.width}px ${canvas.height}px;
							padding: ${canvas.height / 2}px ${canvas.width / 2}px;
							color: transparent;
						`,
					);
					resolve()
				}
			};
		})
	}
	function equal(value1: any, value2: any) {
		// @ts-ignore
		if(import.meta.env.MODE === 'production' && !newconfig.production){
			return;
		}
		queue.add(()=>{
			return new Promise((resolve: any) => {
			    let flag = true;
		if (typeof value1 === 'object' && typeof value2 === 'object') {
			if (typeof value1 !== null && typeof value2 !== null) {
				if (value1 === value2) {
					flag = true;
				} else {
					flag = compareObject(value1, value2);
				}
			} else {
				flag = false;
			}
		} else {
			flag = value1 === value2;
		}
		const canvas = document.createElement('canvas');
		const ctx = canvas.getContext('2d');
		canvas.width = 20;
		canvas.height = 20;
		if (ctx) {
			ctx.fillStyle = 'white';
			ctx.fillRect(0, 0, canvas.width, canvas.height);
			if (flag) {
				ctx.fillStyle = 'green';
				// 3. 绘制绿色的对勾 √
				ctx.strokeStyle = 'green';
				ctx.lineWidth = 2;
				ctx.lineCap = 'round';

				// 绘制对勾的路径
				ctx.beginPath();
				ctx.moveTo(5, 10); // 起点坐标 (x1, y1)
				ctx.lineTo(9, 14); // 中间点坐标 (x2, y2)
				ctx.lineTo(15, 6); // 终点坐标 (x3, y3)
				ctx.stroke();
			} else {
				drawCross(ctx, canvas);
			}
			const imageUrl = canvas.toDataURL('image/png');
			console.log(
				`%c s %c ${JSON.stringify(value1)}===${JSON.stringify(value2)}`,
				`background-image: url(${imageUrl});
					background-repeat: no-repeat;
					background-size: ${canvas.width}px ${canvas.height}px;
					padding: ${canvas.height / 4}px ${canvas.width / 4}px;
					color: transparent;
					background-position: center;
				`,
				`
					margin-left: 5px;
					color: ${flag ? 'green' : 'red'};
					${newconfig.hasborder ? `border: 1px solid ${flag ? 'green' : 'red'};` : ''};,
					padding: 2px 2px;
					border-radius: 5px;
					font-weight: bold;
				`,
			);
			resolve();
		}
			})
		})
	}
	function getinfo(type: string,newconfig: Configtype , title?: string | number) {
		const temp =
			newconfig[
				type as keyof Pick<
					Configtype,
					'info' | 'success' | 'error' | 'warning'
				>
			];
		let infotitle = temp.title;
		if (title) infotitle = title;
		if (newconfig.heightLight) {
			// 示例：计算颜色 "yellow" 的亮色
			try {
				temp.contentColor = getLighterColor(temp.contentColor);
			} catch (error) {
				if (error instanceof ColorError) {
					console.error(
						`ColorError: ${error.message},配置有问题请输入正确的 颜色名称 或者 HEX格式(#ffffff)`,
					);
				} else {
					console.error(`Unexpected error: ${error}`);
				}
			}
		}
		return {
			infoconfig: temp,
			infotitle: infotitle,
		};
	}
	return {
		base,
		info,
		error,
		warning,
		picture,
		equal,
		success
	};
}
function getuserInfo(){
	const userconfig = {}
	const userList = prettyLogconfig.use.userList;
	for(let i = 0 ; i < userList.length ; i++){
		// @ts-ignore
		if(prettyLogconfig.use.userBaseLogs[userList[i].name]){
			// @ts-ignore
			userconfig[userList[i].name]= margeconfig(UserBaseConfig,prettyLogconfig.use.userBaseLogs[userList[i].name]);
		}
	}
	return userconfig;
}
function linstener() {
	// @ts-ignore
	if (import.meta.hot) {
		// @ts-ignore
		import.meta.hot.on('json-update', (data) => {
			// @ts-ignore
			setconfig(data);
            localStorage.setItem('log-jsondata', JSON.stringify(data));
		});
	}
}
function cacheConfig() {
	if(!localStorage.getItem("pre-log-jsondata") ){
        // @ts-ignore
        setconfig(__JSON_CONFIG__);
		// @ts-ignore
        localStorage.setItem('pre-log-jsondata',JSON.stringify(__JSON_CONFIG__));
    } else {
		// @ts-ignore
        if(localStorage.getItem("pre-log-jsondata") === JSON.stringify(__JSON_CONFIG__)) {
            if (localStorage.getItem("log-jsondata")) {
                setconfig(JSON.parse(localStorage.getItem("log-jsondata") || "{}"));
            } else {
				// @ts-ignore
                setconfig(__JSON_CONFIG__);
            }
        } else {
			// @ts-ignore
            setconfig(__JSON_CONFIG__);
			// @ts-ignore
            localStorage.setItem('pre-log-jsondata',JSON.stringify(__JSON_CONFIG__));
            localStorage.removeItem('log-jsondata');
        }
    }
}
function setreturn(FuncData:any,config:Configtype,key?:string){
	// 根据配置决定是否启用扩展功能
	if (key) {
		Log.base[key] = FuncData.base; 
	    if (config.enabled) {
			Log.base[key] = createExtendedFunction(Log.base[key], FuncData, 'base');
		} else {
			Log.base[key] = function (...args:any) {
				console.log(...args);
			};
			Log.base[key] = createExtendedFunction(Log.base[key], FuncData);
		}
	} else {
		if (config.enabled) {
			Log.base = createExtendedFunction(Log.base, FuncData, 'base');
		} else {
			Log.base = function (...args:any) {
				console.log(...args);
			};
			Log.base = createExtendedFunction(Log.base, FuncData);
		}
	}
}

function getUserAndBaseFunc(){
	const userConfig = getuserInfo();
	if(Object.keys(userConfig).length > 0){
		const userKeys = Object.keys(userConfig);
		for(let i = 0 ; i < userKeys.length ; i++){
			// @ts-ignore
			const curUserConfig = userConfig[userKeys[i]];
			const curUserFuncData = prettyLog(curUserConfig, userKeys[i]);
		    setreturn(curUserFuncData, curUserConfig,userKeys[i]);
		}
	}
}
// @ts-ignore
const baseLog = function () {
	try {
		cacheConfig();
		Log = prettyLog(prettyLogconfig);
		setreturn(Log,prettyLogconfig);
		getUserAndBaseFunc();
		returnLog = Log.base;
	} catch (error) {
		console.error('Error fetching configuration:', error);
		return function (...args: any) {
			console.log(...args);
		};
	}
};


linstener();
baseLog();

export default returnLog;




